<template>
  <vxe-grid
    ref="table"
    :class="['table-tree', 'mytable-scrollbar', { isEdit: isEdit }]"
    show-overflow
    row-key
    border
    keep-source
    :data="tableData"
    :tree-config="{
      line: true,
      parentField: 'parentTag',
      rowField: 'tag',
      transform: true,
      iconOpen: '',
      iconClose: 'vxe-icon-square-plus',
    }"
    :columns="columns"
    v-bind="isEdit ? vexOptions : null"
    @cell-click="cellClickEvent"
    @edit-actived="editActivedEvent"
  >
    <!-- <template #icon_default="{ row }">
      <template v-if="row.children && row.children.length">
        <i :class="$refs.table.isTreeExpandByRow(row) ? 'vxe-open_file' : 'vxe-close_file'"></i>
      </template>
      <template v-else>
        <i class="circle"></i>
      </template>
    </template> -->
    <template #field_default="{ row }">
      <template v-if="row.children && row.children.length">
        <i :class="$refs.table.isTreeExpandByRow(row) ? 'vxe-open_file' : 'vxe-close_file'"></i>
      </template>
      <template v-else>
        <i class="vxe-circle"></i>
      </template>
      <span>{{ row.field }}</span>
    </template>
    <template #field_edit="scope">
      <template v-if="scope.row.children && scope.row.children.length">
        <i :class="$refs.table.isTreeExpandByRow(scope.row) ? 'vxe-open_file' : 'vxe-close_file'"></i>
      </template>
      <template v-else>
        <i class="vxe-circle"></i>
      </template>
      <vxe-input v-model="scope.row.field" type="text" @change="$refs.table.updateStatus(scope)"></vxe-input>
    </template>
    <template #status_default="{ row }">
      <span>{{ row.enabledFlag | formatStatus }}</span>
    </template>
    <template #status_edit="{ row }">
      <vxe-select v-model="row.enabledFlag" transfer>
        <vxe-option v-for="item in statuss" :key="item.value" :value="item.value" :label="item.label"></vxe-option>
      </vxe-select>
    </template>
    <template #type_default="{ row }">
      <span>{{ row.type }}</span>
    </template>
    <template #type_edit="{ row }">
      <vxe-select v-model="row.type" transfer :disabled="isType" :clearable="!isType">
        <vxe-option v-for="item in types" :key="item.name" :value="item.name" :label="item.name"></vxe-option>
      </vxe-select>
    </template>
    <template #lineNumber_default="{ row }">
      <span>{{ row.lineNumber | formatLineNumber(row) }}</span>
    </template>
    <template #lineNumber_edit="scope">
      <vxe-input
        v-model="scope.row.lineNumber"
        type="number"
        :disabled="isLineNumber"
        @change="$refs.table.updateStatus(scope)"
      ></vxe-input>
    </template>
    <template #startColumn_default="{ row }">
      <span>{{ row.startColumn || '' }}</span>
    </template>
    <template #startColumn_edit="scope">
      <vxe-select
        v-model="scope.row.startColumn"
        transfer
        :disabled="isStartColumn"
        @change="$refs.table.updateStatus(scope)"
      >
        <vxe-option v-for="num in nums" :key="num" :value="num" :label="num"></vxe-option>
      </vxe-select>
    </template>
    <template #endColumn_default="{ row }">
      <span>{{ row.endColumn || '-' }}</span>
    </template>
    <template #endColumn_edit="scope">
      <vxe-select
        v-model="scope.row.endColumn"
        transfer
        :disabled="isEndColumn"
        @change="$refs.table.updateStatus(scope)"
      >
        <vxe-option v-for="num in nums" :key="num" :value="num" :label="num"></vxe-option>
      </vxe-select>
    </template>
    <!-- <template #operate_item="{ data }">
          <vxe-button type="submit" status="primary" content="查询" />
          <vxe-button type="reset" content="重置" @click="haha(data)" />
        </template> -->
    <template #operate_item="{ row }">
      <vxe-button v-if="!row.parentTag" type="text" status="primary" @click="add(row)">添加子级</vxe-button>
      <vxe-button type="text" status="danger" @click="del(row)">删除</vxe-button>
    </template>
  </vxe-grid>
</template>
<script>
import VXETable from 'vxe-table';
import Sortable from 'sortablejs';
import XEUtils from 'xe-utils';
export default {
  props: {
    isEdit: {
      type: Boolean,
      default: false,
    },
    columns: { type: Array, default: () => [] },
  },
  data() {
    const lineNumberValid = ({ row, cellValue }) => {
      const $table = this.$refs.table.$refs.xTable;
      const list = $table.afterTreeFullData.map((item) => item.children).flat(1);
      for (let i = 0; i < list.length; i++) {
        if (Number(list[i]?.lineNumber) > Number(list[i + 1]?.lineNumber)) {
          if (row?._X_ROW_KEY === list[i + 1]?._X_ROW_KEY) {
            return new Error('行号不合格');
          }
        }
      }
    };
    const startColumnValid = ({ row, cellValue }) => {
      const $table = this.$refs.table.$refs.xTable;
      const list = $table.afterTreeFullData.map((item) => item.children).flat(1);
      for (let i = 0; i < list.length; i++) {
        if (Number(list[i]?.lineNumber) == Number(list[i + 1]?.lineNumber)) {
          if (list[i]?.endColumn >= list[i + 1]?.startColumn) {
            if (row?._X_ROW_KEY === list[i + 1]?._X_ROW_KEY) {
              return new Error('开始列不合格');
            }
          }
        }
        if (Number(list[i]?.startColumn) % 2 !== 0) {
          if (row?._X_ROW_KEY === list[i]?._X_ROW_KEY) {
            return new Error('开始列应该从偶数开始');
          }
        }
      }
    };
    const endColumnValid = ({ row, cellValue }) => {
      const $table = this.$refs.table.$refs.xTable;
      const list = $table.afterTreeFullData.map((item) => item.children).flat(1);
      for (let i = 0; i < list.length; i++) {
        if (list[i]?.endColumn <= list[i]?.startColumn) {
          if (row?._X_ROW_KEY === list[i]?._X_ROW_KEY) {
            return new Error('结束列不合格');
          }
        }
        if ((list[i]?.endColumn - list[i]?.startColumn + 1) % 2 !== 0) {
          if (row?._X_ROW_KEY === list[i]?._X_ROW_KEY) {
            return new Error('开始列-结束列的列数应为偶数');
          }
        }
      }
    };
    const validRules = {
      field: [{ required: true, message: '字段不能为空' }],
      lineNumber: [{ required: true, validator: lineNumberValid }],
      startColumn: [{ required: true, validator: startColumnValid }],
      endColumn: [{ required: true, validator: endColumnValid }],
    };
    return {
      vexOptions: {
        'edit-rules': validRules,
        'scroll-y': { enabled: false },
        'row-config': { useKey: true, isHover: true, isCurrent: true },
        'radio-config': { labelField: 'groupName' },
        'edit-config': { trigger: 'click', mode: 'row', showStatus: true, showIcon: false },
      },
      types: [
        {
          name: '项目商务状态档案',
        },
      ],
      isField: false,
      isType: false,
      isLineNumber: false,
      isStartColumn: false,
      isEndColumn: false,
      tableData: [],
      selectRow: null,
      nums: [2, 3, 4, 5, 6, 7, 8, 9],
      mergeCells: [],
      atozStr: 'ABCDEFGHI',
      atozArr: ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I'],
      statuss: [
        { label: '禁用', value: false },
        { label: '启用', value: true },
      ],
    };
  },
  filters: {
    formatStatus(val) {
      return val ? '启用' : '禁用';
    },
    formatLineNumber(lineNumber, row) {
      let result = lineNumber;
      const child = row.children;
      if (child && child.length > 0) {
        const start = child[0].lineNumber;
        const end = child[child.length - 1].lineNumber;
        result = start !== end && start < end ? `${start}-${end}` : start;
      }
      return result;
    },
  },
  created() {
    // this.treeDrop();
  },
  mounted() {
    this.getList();
  },
  methods: {
    treeDrop() {
      this.$nextTick(() => {
        const $table = this.$refs.table;
        this.sortable2 = Sortable.create($table.$el.querySelector('.body--wrapper>.vxe-table--body tbody'), {
          handle: '.drag-btn',
          onEnd: ({ item, oldIndex }) => {
            const options = { children: 'children' };
            const targetTrElem = item;
            const wrapperElem = targetTrElem.parentNode;
            const prevTrElem = targetTrElem.previousElementSibling;
            const tableData = this.tableData;
            const selfRow = $table.getRowNode(targetTrElem).item;
            const selfNode = XEUtils.findTree(tableData, (row) => row === selfRow, options);
            if (prevTrElem) {
              // 移动到节点
              const prevRow = $table.getRowNode(prevTrElem).item;
              const prevNode = XEUtils.findTree(tableData, (row) => row === prevRow, options);
              if (XEUtils.findTree(selfRow[options.children], (row) => prevRow === row, options)) {
                // 错误的移动
                const oldTrElem = wrapperElem.children[oldIndex];
                wrapperElem.insertBefore(targetTrElem, oldTrElem);
                return VXETable.modal.message({ content: '不允许自己给自己拖动！', status: 'error' });
              }
              const currRow = selfNode.items.splice(selfNode.index, 1)[0];
              if ($table.isTreeExpandByRow(prevRow)) {
                // 移动到当前的子节点
                prevRow[options.children].splice(0, 0, currRow);
              } else {
                // 移动到相邻节点
                prevNode.items.splice(prevNode.index + (selfNode.index < prevNode.index ? 0 : 1), 0, currRow);
              }
            } else {
              // 移动到第一行
              const currRow = selfNode.items.splice(selfNode.index, 1)[0];
              tableData.unshift(currRow);
            }
            // 如果变动了树层级，需要刷新数据
            this.tableData = [...tableData];
          },
        });
      });
    },
    async getList() {
      await this.$api
        .ApiOperationalPageList({
          enabledFlag: true,
          page: 0,
          size: 1000,
        })
        .then((res) => {
          function flatten(arr = [], dep, parent = {}) {
            return arr.reduce(function (prev, item) {
              item.tag = item.id;
              item.parentTag = item.parentId;
              return prev.concat(item, flatten(item.children || [], dep + 1, item));
            }, []);
          }
          this.total = res.total;
          this.tableData = flatten(res.list, 1);
        });
    },
    editActivedEvent({ row, rowIndex }) {
      this.isField = row.id && !row.parentTag;
      this.isType = !row.parentTag;
      this.isLineNumber = !row.parentTag;
      this.isStartColumn = !row.parentTag;
      this.isEndColumn = !row.parentTag;
    },
    async add(currRow) {
      const $table = this.$refs.table;
      const record = {
        // parentId: currRow.id, // 需要指定父节点，自动插入该节点中
        tag: Date.now() + '',
        parentTag: currRow.tag,
        field: '',
        type: '',
        lineNumber: '',
        startColumn: null,
        endColumn: null,
      };
      const { row: newRow } = await $table.insertAt(record, -1);
      await $table.setTreeExpand(currRow, true); // 将父节点展开
      await $table.setActiveRow(newRow); // 插入子节点
    },
    async del(row) {
      this.confirmEvent(row);
    },
    cellClickEvent(item) {
      this.selectRow = item;
    },
    confirmEvent(row) {
      const $table = this.$refs.table;
      VXETable.modal.confirm('删除后需要重新对行和列进行重新排序，是否确认删除？').then(async (type) => {
        if (type === 'confirm') {
          await $table.remove(row);
        }
      });
    },
    async fullValidEvent() {
      const $table = this.$refs.table;
      const errMap = await $table.fullValidate().catch((errMap) => errMap);
      if (errMap) {
        const msgList = [];
        Object.values(errMap).forEach((errList) => {
          errList.forEach((params) => {
            const { rowIndex, column, rules } = params;
            rules.forEach((rule) => {
              msgList.push(`校验错误：${rule.message}`);
            });
          });
        });
        VXETable.modal.message({
          status: 'error',
          slots: {
            default() {
              return [
                <div class="red" style="max-height: 400px;overflow: auto;">
                  {msgList.map((msg) => (
                    <div>{msg}</div>
                  ))}
                </div>,
              ];
            },
          },
        });
      } else {
        VXETable.modal.message({ status: 'success', content: '校验成功！' });
        this.$emit('submit');
      }
    },
  },
};
</script>
<style lang="scss">
.mytable-scrollbar {
  .vxe-table--main-wrapper {
    height: calc(100vh - 70px);
    .vxe-table--body-wrapper {
      height: calc(100% - 50px);
    }
  }
}
.table-tree.isEdit {
  .vxe-table--main-wrapper {
    height: calc(100vh - 120px);
    .vxe-table--body-wrapper {
      height: calc(100% - 50px);
    }
  }
}
</style>
